package eerbaar.client.internal.ctr.operator;

import eerbaar.area.IArea;
import eerbaar.client.ctr.IPersonaCmd;
import eerbaar.client.exp.IExp;
import eerbaar.client.internal.ctr.cmd.DecrementXCmd;
import eerbaar.client.internal.ctr.cmd.DecrementXDecrementYCmd;
import eerbaar.client.internal.ctr.cmd.DecrementXIncrementYCmd;
import eerbaar.client.internal.ctr.cmd.DecrementYCmd;
import eerbaar.client.internal.ctr.cmd.IncrementXCmd;
import eerbaar.client.internal.ctr.cmd.IncrementXDecrementYCmd;
import eerbaar.client.internal.ctr.cmd.IncrementXIncrementYCmd;
import eerbaar.client.internal.ctr.cmd.IncrementYCmd;
import eerbaar.client.internal.ctr.pet.PersonExpression;
import eerbaar.elements.IElement;
import eerbaar.game.GameFactory;
import eerbaar.game.IGame;
import eerbaar.persona.IPersona;
import eerbaar.position.IPosition;
import eerbaar.position.PositionFactory;

public class Global {

    static IPosition calcDestination(IPersona pet, IPosition subject,
            IPosition target) {

        final int sourceX = subject.getX();
        final int sourceY = subject.getY();
        int destinationX = target.getX();
        int destinationY = target.getY();

        int x = sourceX;
        int y = sourceY;

        if (sourceX < destinationX) {
            x++;
        } else if (sourceX > destinationX) {
            x--;
        } else if (sourceY < destinationY) {
            y++;
        } else if (sourceY > destinationY) {
            y--;
        }

        return PositionFactory.createPosition(x, y);
    }

    public static double calcDistance(IPosition start, IPosition end) {

        double x1 = start.getX();
        double y1 = start.getY();
        double x2 = end.getX();
        double y2 = end.getY();

        double xDelta;
        if (x1 > x2) {
            xDelta = (x1 - x2);
        } else {
            xDelta = (x2 - x1);
        }

        double yDelta;
        if (y1 > y2) {
            yDelta = (y1 - y2);
        } else {
            yDelta = (y2 - y1);
        }

        double xPart = (xDelta) * (xDelta);
        double yPart = (yDelta) * (yDelta);
        double distance = Math.sqrt(xPart + yPart);

        return distance;
    }

    public static int calcLength(IPosition start, IPosition end) {

        int x1 = start.getX();
        int y1 = start.getY();
        int x2 = end.getX();
        int y2 = end.getY();

        double deltaX = Math.abs(x1 - x2);
        double deltaY = Math.abs(y1 - y2);
        int length = (int) Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
        return length;
    }

    static IExp calcMoveTo(IGame game, IPersona pet, IPosition subject,
            IPosition target) {

        final int sourceX = subject.getX();
        final int sourceY = subject.getY();
        int destinationX = target.getX();
        int destinationY = target.getY();

        IPersonaCmd cmd = null;

        if (sourceX > destinationX && sourceY > destinationY) {
            cmd = new DecrementXDecrementYCmd();
        } else if (sourceX > destinationX && sourceY < destinationY) {
            cmd = new DecrementXIncrementYCmd();
        } else if (sourceX < destinationX && sourceY > destinationY) {
            cmd = new IncrementXDecrementYCmd();
        } else if (sourceX < destinationX && sourceY < destinationY) {
            cmd = new IncrementXIncrementYCmd();
        } else if (sourceX < destinationX) {
            cmd = new IncrementXCmd();
        } else if (sourceX > destinationX) {
            cmd = new DecrementXCmd();
        } else if (sourceY < destinationY) {
            cmd = new IncrementYCmd();
        } else if (sourceY > destinationY) {
            cmd = new DecrementYCmd();
        }
        if (cmd == null) {
            return null;
        }

        return new PersonExpression(game, pet, cmd);
    }

    public static IGame copyGame(IGame inGame) {

        IGame result = GameFactory.createGame();

        IPersona[] array = result.getPersonas();
        for (IPersona p : array) {
            result.getArea().removeElement(p);
        }

        IElement[] elements = inGame.getArea().getElements();
        for (IElement e : elements) {
            IElement copy = e.copy();
            result.getArea().addElement(copy);
        }

        return result;
    }

    static IElement findClosest(IGame game, IPosition start, String name) {

        IElement result = null;

        double closest = 9999;

        IArea area = game.getArea();
        IElement[] elements = area.getElements();
        for (IElement e : elements) {

            if (e.getName().equals(name)) {

                double distance = calcDistance(start, e.getPosition());
                if (distance < closest) {

                    closest = distance;
                    result = e;
                }
            }
        }

        return result;
    }

}
